/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2016 Marvell, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#ifndef __SOC_MARVELL_MVMAP2315_SDRAM_H__
#define __SOC_MARVELL_MVMAP2315_SDRAM_H__

#include <stdint.h>

#include <soc/addressmap.h>
#include <types.h>

struct mvmap2315_sdram_params {
	u32  dphy_params[100];
	u32  mc_params[122];
};

struct mvmap2315_dphy_regs {
	u32 dphy_id;
	u32 dphy_phy_user0;
	u8 reserved0[0x04];
	u32 dphy_flag;
	u32 dphy_dq_pad_ctrl0;
	u32 dphy_dq_pad_ctrl2;
	u8 reserved1[0x08];
	u32 dphy_ck_pad_ctrl0;
	u32 dphy_ck_pad_ctrl2;
	u8 reserved2[0x04];
	u32 dphy_ck_pad_ctrl6;
	u32 dphy_adcm_pad_ctrl0;
	u32 dphy_adcm_pad_ctrl2;
	u8 reserved3[0x28];
	u32 dphy_dfi_ctrl0;
	u32 dphy_dfi_ctrl2;
	u32 dphy_dfi_ctrl4;
	u32 dphy_dfi_ctrl6;
	u32 dphy_wl_ctrl0;
	u8 reserved4[0x0c];
	u32 dphy_qsg_ctrl0;
	u8 reserved5[0x0c];
	u32 dphy_qsg_d_ctrl0;
	u8 reserved6[0x1c];
	u32 dphy_rdlvl_ctrl0;
	u8 reserved7[0x0c];
	u32 dphy_cal_pad_ctrl0;
	u32 dphy_cal_pad_ctrl2;
	u32 dphy_dll_vreg_ctrl;
	u32 dphy_vref_ctrl0;
	u32 dphy_cat_ctrl0;
	u32 dphy_cat_stat0;
	u32 dphy_cat_stat2;
	u32 dphy_cat_stat4;
	u32 dphy_cat_marg0;
	u32 dphy_cat_marg2;
	u32 dphy_cat_marg4;
	u32 dphy_cat_mctl;
	u32 dphy_apb_ctrl0;
	u32 dphy_monitor;
	u32 dphy_adcm_reserve;
	u8 reserved8[0x04];
	u32 dphy_dll_ctrl_0;
	u8 reserved9[0x1c];
	u32 dphy_dll_ctrl0;
	u32 dphy_dll_ctrl2;
	u8 reserved10[0x04];
	u32 dphy_dll_tst_out;
	u8 reserved11[0x10];
	u32 dphy_dq_dly_ctrl0;
	u8 reserved12[0x1c];
	u32 dphy_qs_dly_ctrl0;
	u8 reserved13[0x5c];
	u32 dphy_dll_phrng0;
	u8 reserved14[0x3c];
	u32 dphy_ca_dly_ctrl0;
	u32 dphy_ca_dly_ctrl1;
	u32 dphy_ca_dly_ctrl2;
	u32 dphy_ca_dly_ctrl3;
	u32 dphy_ca_dly_ctrl4;
	u8 reserved15[0x0c];
	u32 dphy_ad0_dly_ctrl;
	u8 reserved16[0x0c];
	u32 dphy_ck_dly_ctrl0;
	u8 reserved17[0x5c];
	u32 dphy_qsg_d_out0;
	u8 reserved18[0x12c];
	u32 dphy_lb_ctrl0;
	u32 dphy_lb_sts0;
	u32 dphy_lb_cnt0;
	u8 reserved19[0x04];
	u32 dphy_lb_seed0;
	u32 dphy_lb_seed2;
};

check_member(mvmap2315_dphy_regs, dphy_lb_seed2, 0x3D4);
static struct mvmap2315_dphy_regs * const mvmap2315_dphy0
					= (void *)MVMAP2315_PHY0_BASE;
static struct mvmap2315_dphy_regs * const mvmap2315_dphy1
					= (void *)MVMAP2315_PHY1_BASE;
static struct mvmap2315_dphy_regs * const mvmap2315_dphy2
					= (void *)MVMAP2315_PHY2_BASE;
static struct mvmap2315_dphy_regs * const mvmap2315_dphy3
					= (void *)MVMAP2315_PHY3_BASE;

#define MVMAP2315_MC_DRAM_READY			BIT(0)
struct mvmap2315_mc_regs {
	u32 mc_id;
	u32 mc_status_ch0;
	u32 dram_status;
	u8 reserved0[0x04];
	u32 mc_status_ch1;
	u32 mc_status_ch2;
	u32 mc_status_ch3;
	u32 dram_status1;
	u32 user_command_0;
	u32 user_command_1;
	u32 user_command_2;
	u32 user_command_3;
	u8 reserved1[0x10];
	u32 sram_control;
	u32 mc_control_0;
	u32 exclusive_monitor;
	u32 ras_control;
	u32 spool_control;
	u32 mc_pwr_ctl;
	u32 wb_control;
	u32 cat_priority_ctl;
	u32 rob_control;
	u32 rdp_control;
	u32 axi_port_control;
	u32 wb_control1;
	u32 regtable_control;
	u32 regtable_data_0;
	u32 regtable_data_1;
	u32 rz_access_ctl;
	u32 tz_range0_low;
	u32 tz_range0_high;
	u32 tz_range1_low;
	u32 tz_range1_high;
	u32 tz_range2_low;
	u32 tz_range2_high;
	u32 tz_range3_low;
	u32 tz_range3_high;
	u32 tz_range4_low;
	u32 tz_range4_high;
	u32 tz_range5_low;
	u32 tz_range5_high;
	u32 tz_range6_low;
	u32 tz_range6_high;
	u32 tz_range7_low;
	u32 tz_range7_high;
	u32 tz_range8_low;
	u32 tz_range8_high;
	u32 tz_range9_low;
	u32 tz_range9_high;
	u32 tz_range10_low;
	u32 tz_range10_high;
	u32 tz_range11_low;
	u32 tz_range11_high;
	u32 tz_range12_low;
	u32 tz_range12_high;
	u32 tz_range13_low;
	u32 tz_range13_high;
	u32 tz_range14_low;
	u32 tz_range14_high;
	u32 tz_range15_low;
	u32 tz_range15_high;
	u32 pc_config0;
	u32 pc_config1;
	u32 pc_status;
	u32 pc_control;
	u32 pc0;
	u32 pc1;
	u32 pc2;
	u32 pc3;
	u32 pc4;
	u32 pc5;
	u32 pc6;
	u32 pc7;
	u8 reserved2[0x10];
	u32 isr;
	u32 ier;
	u8 reserved3[0x08];
	u32 adc_err_id;
	u32 adc_err_adr_l;
	u32 adc_err_adr_h;
	u8 reserved4[0x04];
	u32 am_period;
	u32 am_th;
	u8 reserved5[0x08];
	u32 am2_period;
	u32 am2_low_th;
	u32 am2_high_th;
	u32 am2_busy_cycle;
	u32 rpp_starvation_control;
	u32 bw_allocation_tc_window0;
	u32 bw_allocation_tc_window1;
	u32 bw_allocation_tc_window2;
	u32 bw_allocation_tc_window3;
	u32 bw_allocation_tc_window4;
	u32 bw_allocation_tc_window5;
	u32 bw_allocation_tc_window6;
	u32 bw_allocation_tc_window7;
	u32 bw_allocation_tc_window8;
	u32 bw_allocation_tc_window9;
	u32 bw_allocation_tc_window10;
	u32 bw_allocation_tc_window11;
	u32 bw_allocation_tc_window12;
	u32 bw_allocation_tc_window13;
	u32 bw_allocation_tc_window14;
	u32 bw_allocation_tc_window15;
	u32 cat_priority_ctl_ddr4;
	u8 reserved6[0x38];
	u32 mmap0_low_ch0;
	u32 mmap0_high_ch0;
	u32 mmap1_low_ch0;
	u32 mmap1_high_ch0;
	u8 reserved7[0x10];
	u32 ch0_mc_config_cs0;
	u32 ch0_mc_config_cs1;
	u8 reserved8[0x98];
	u32 ch0_mc_control_1;
	u32 ch0_mc_control_2;
	u32 ch0_mc_control_3;
	u32 ch0_mc_control_4;
	u8 reserved9[0x30];
	u32 ch0_dram_config_1;
	u32 ch0_dram_config_2;
	u32 ch0_dram_config_3;
	u32 ch0_dram_config_4;
	u32 ch0_dram_config_5_cs0;
	u32 ch0_dram_config_5_cs1;
	u8 reserved10[0x08];
	u32 ch0_dram_config_6;
	u32 ch0_dram_config_7;
	u32 ch0_dram_config_8;
	u32 ch0_dram_config_9;
	u32 ch0_dram_config_10;
	u32 ch0_dram_config_11;
	u32 ch0_dram_config_12;
	u8 reserved11;
	u32 ch0_odt_control_0;
	u32 ch0_odt_control_1;
	u32 ch0_odt_control_2;
	u32 ch0_odt_control_3;
	u32 ch0_rdimm_config_0;
	u32 ch0_rdimm_config_1;
	u32 ch0_rdimm_config_2;
	u32 ch0_rdimm_config_3;
	u8 reserved12[0x10];
	u32 ch0_mrr_data;
	u8 reserved13[0x0c];
	u32 ch0_ddr_init_timing_control_0;
	u32 ch0_ddr_init_timing_control_1;
	u32 ch0_ddr_init_timing_control_2;
	u32 ch0_zqc_timing_0;
	u32 ch0_zqc_timing_1;
	u32 ch0_refresh_timing;
	u32 ch0_selfrefresh_timing_0;
	u32 ch0_selfrefresh_timing_1;
	u32 ch0_powerdown_timing_0;
	u32 ch0_powerdown_timing_1;
	u32 ch0_mrs_timing;
	u32 ch0_act_timing;
	u32 ch0_precharge_timing;
	u32 ch0_cas_ras_timing_0;
	u32 ch0_cas_ras_timing_1;
	u32 ch0_off_spec_timing_0;
	u32 ch0_off_spec_timing_1;
	u32 ch0_dram_read_timing;
	u32 ch0_dram_ca_train_timing;
	u8 reserved14[0x0c];
	u32 ch0_dram_training_timing;
	u32 ch0_rdimm_timing_0;
	u32 ch0_rdimm_timing_1;
	u8 reserved15[0x1c];
	u32 mmap0_low_ch1;
	u32 mmap0_high_ch1;
	u32 mmap1_low_ch1;
	u32 mmap1_high_ch1;
	u8 reserved16[0x10];
	u32 ch1_mc_config_cs0;
	u32 ch1_mc_config_cs1;
	u8 reserved17[0x98];
	u32 ch1_mc_control_1;
	u32 ch1_mc_control_2;
	u32 ch1_mc_control_3;
	u32 ch1_mc_control_4;
	u8 reserved18[0x30];
	u32 ch1_dram_config_1;
	u32 ch1_dram_config_2;
	u32 ch1_dram_config_3;
	u32 ch1_dram_config_4;
	u32 ch1_dram_config_5_cs0;
	u32 ch1_dram_config_5_cs1;
	u8 reserved19[0x08];
	u32 ch1_dram_config_6;
	u32 ch1_dram_config_7;
	u32 ch1_dram_config_8;
	u32 ch1_dram_config_9;
	u32 ch1_dram_config_10;
	u32 ch1_dram_config_11;
	u32 ch1_dram_config_12;
	u8 reserved20[0x04];
	u32 ch1_odt_control_0;
	u32 ch1_odt_control_1;
	u32 ch1_odt_control_2;
	u32 ch1_odt_control_3;
	u32 ch1_rdimm_config_0;
	u32 ch1_rdimm_config_1;
	u32 ch1_rdimm_config_2;
	u32 ch1_rdimm_config_3;
	u8 reserved21[0x10];
	u32 ch1_mrr_data;
	u8 reserved22[0x0c];
	u32 ch1_ddr_init_timing_control_0;
	u32 ch1_ddr_init_timing_control_1;
	u32 ch1_ddr_init_timing_control_2;
	u32 ch1_zqc_timing_0;
	u32 ch1_zqc_timing_1;
	u32 ch1_refresh_timing;
	u32 ch1_selfrefresh_timing_0;
	u32 ch1_selfrefresh_timing_1;
	u32 ch1_powerdown_timing_0;
	u32 ch1_powerdown_timing_1;
	u32 ch1_mrs_timing;
	u32 ch1_act_timing;
	u32 ch1_precharge_timing;
	u32 ch1_cas_ras_timing_0;
	u32 ch1_cas_ras_timing_1;
	u32 ch1_off_spec_timing_0;
	u32 ch1_off_spec_timing_1;
	u32 ch1_dram_read_timing;
	u32 ch1_dram_ca_train_timing;
	u8 reserved23[0x0c];
	u32 ch1_dram_training_timing;
	u32 ch1_rdimm_timing_0;
	u32 ch1_rdimm_timing_1;
	u8 reserved24[0x1c];
	u32 mmap0_low_ch2;
	u32 mmap0_high_ch2;
	u32 mmap1_low_ch2;
	u32 mmap1_high_ch2;
	u8 reserved25[0x10];
	u32 ch2_mc_config_cs0;
	u32 ch2_mc_config_cs1;
	u8 reserved26[0x98];
	u32 ch2_mc_control_1;
	u32 ch2_mc_control_2;
	u32 ch2_mc_control_3;
	u32 ch2_mc_control_4;
	u8 reserved27[0x30];
	u32 ch2_dram_config_1;
	u32 ch2_dram_config_2;
	u32 ch2_dram_config_3;
	u32 ch2_dram_config_4;
	u32 ch2_dram_config_5_cs0;
	u32 ch2_dram_config_5_cs1;
	u8 reserved28[0x08];
	u32 ch2_dram_config_6;
	u32 ch2_dram_config_7;
	u32 ch2_dram_config_8;
	u32 ch2_dram_config_9;
	u32 ch2_dram_config_10;
	u32 ch2_dram_config_11;
	u32 ch2_dram_config_12;
	u8 reserved29[0x04];
	u32 ch2_odt_control_0;
	u32 ch2_odt_control_1;
	u32 ch2_odt_control_2;
	u32 ch2_odt_control_3;
	u32 ch2_rdimm_config_0;
	u32 ch2_rdimm_config_1;
	u32 ch2_rdimm_config_2;
	u32 ch2_rdimm_config_3;
	u8 reserved30[0x10];
	u32 ch2_mrr_data;
	u8 reserved31[0x0c];
	u32 ch2_ddr_init_timing_control_0;
	u32 ch2_ddr_init_timing_control_1;
	u32 ch2_ddr_init_timing_control_2;
	u32 ch2_zqc_timing_0;
	u32 ch2_zqc_timing_1;
	u32 ch2_refresh_timing;
	u32 ch2_selfrefresh_timing_0;
	u32 ch2_selfrefresh_timing_1;
	u32 ch2_powerdown_timing_0;
	u32 ch2_powerdown_timing_1;
	u32 ch2_mrs_timing;
	u32 ch2_act_timing;
	u32 ch2_precharge_timing;
	u32 ch2_cas_ras_timing_0;
	u32 ch2_cas_ras_timing_1;
	u32 ch2_off_spec_timing_0;
	u32 ch2_off_spec_timing_1;
	u32 ch2_dram_read_timing;
	u32 ch2_dram_ca_train_timing;
	u8 reserved32[0x0c];
	u32 ch2_dram_training_timing;
	u32 ch2_rdimm_timing_0;
	u32 ch2_rdimm_timing_1;
	u8 reserved33[0x1c];
	u32 mmap0_low_ch3;
	u32 mmap0_high_ch3;
	u32 mmap1_low_ch3;
	u32 mmap1_high_ch3;
	u8 reserved34[0x10];
	u32 ch3_mc_config_cs0;
	u32 ch3_mc_config_cs1;
	u8 reserved35[0x98];
	u32 ch3_mc_control_1;
	u32 ch3_mc_control_2;
	u32 ch3_mc_control_3;
	u32 ch3_mc_control_4;
	u8 reserved36[0x30];
	u32 ch3_dram_config_1;
	u32 ch3_dram_config_2;
	u32 ch3_dram_config_3;
	u32 ch3_dram_config_4;
	u32 ch3_dram_config_5_cs0;
	u32 ch3_dram_config_5_cs1;
	u8 reserved37[0x08];
	u32 ch3_dram_config_6;
	u32 ch3_dram_config_7;
	u32 ch3_dram_config_8;
	u32 ch3_dram_config_9;
	u32 ch3_dram_config_10;
	u32 ch3_dram_config_11;
	u32 ch3_dram_config_12;
	u8 reserved38[0x04];
	u32 ch3_odt_control_0;
	u32 ch3_odt_control_1;
	u32 ch3_odt_control_2;
	u32 ch3_odt_control_3;
	u32 ch3_rdimm_config_0;
	u32 ch3_rdimm_config_1;
	u32 ch3_rdimm_config_2;
	u32 ch3_rdimm_config_3;
	u8 reserved39[0x10];
	u32 ch3_mrr_data;
	u8 reserved40[0x0c];
	u32 ch3_ddr_init_timing_control_0;
	u32 ch3_ddr_init_timing_control_1;
	u32 ch3_ddr_init_timing_control_2;
	u32 ch3_zqc_timing_0;
	u32 ch3_zqc_timing_1;
	u32 ch3_refresh_timing;
	u32 ch3_selfrefresh_timing_0;
	u32 ch3_selfrefresh_timing_1;
	u32 ch3_powerdown_timing_0;
	u32 ch3_powerdown_timing_1;
	u32 ch3_mrs_timing;
	u32 ch3_act_timing;
	u32 ch3_precharge_timing;
	u32 ch3_cas_ras_timing_0;
	u32 ch3_cas_ras_timing_1;
	u32 ch3_off_spec_timing_0;
	u32 ch3_off_spec_timing_1;
	u32 ch3_dram_read_timing;
	u32 ch3_dram_ca_train_timing;
	u8 reserved41[0x0c];
	u32 ch3_dram_training_timing;
	u32 ch3_rdimm_timing_0;
	u32 ch3_rdimm_timing_1;
	u8 reserved42[0x6c];
	u32 test_control;
	u8 reserved43[0x0c];
	u32 user_trigger_ir;
	u8 reserved44[0x08];
	u32 training_control;
	u32 training_pattern0;
	u32 training_pattern1;
	u32 training_pattern2;
	u32 training_pattern3;
	u32 training_pattern4;
	u32 training_pattern5;
	u32 training_pattern6;
	u32 training_pattern7;
	u32 dmi_training_pattern;
	u8 reserved45[0x93c];
	u32 dfi_phy_user_command_0;
	u8 reserved46[0x0c];
	u32 ch0_dfi_phy_control_0;
	u32 ch0_dfi_phy_control_1;
	u32 ch0_dfi_phy_control_2;
	u32 ch0_dfi_phy_control_3;
	u32 ch0_dfi_phy_ca_train;
	u32 ch0_dfi_phy_ca_pattern;
	u32 ch0_dfi_phy_write_dq_train;
	u32 ch0_dfi_phy_leveling_status;
	u8 reserved47[0x3e0];
	u32 ch1_dfi_phy_control_0;
	u32 ch1_dfi_phy_control_1;
	u32 ch1_dfi_phy_control_2;
	u32 ch1_dfi_phy_control_3;
	u32 ch1_dfi_phy_ca_train;
	u32 ch1_dfi_phy_ca_pattern;
	u32 ch1_dfi_phy_write_dq_train;
	u32 ch1_dfi_phy_leveling_status;
	u8 reserved48[0x3e0];
	u32 ch2_dfi_phy_control_0;
	u32 ch2_dfi_phy_control_1;
	u32 ch2_dfi_phy_control_2;
	u32 ch2_dfi_phy_control_3;
	u32 ch2_dfi_phy_ca_train;
	u32 ch2_dfi_phy_ca_pattern;
	u32 ch2_dfi_phy_write_dq_train;
	u32 ch2_dfi_phy_leveling_status;
	u8 reserved49[0x3e0];
	u32 ch3_dfi_phy_control_0;
	u32 ch3_dfi_phy_control_1;
	u32 ch3_dfi_phy_control_2;
	u32 ch3_dfi_phy_control_3;
	u32 ch3_dfi_phy_ca_train;
	u32 ch3_dfi_phy_ca_pattern;
	u32 ch3_dfi_phy_write_dq_train;
	u32 ch3_dfi_phy_leveling_status;
};

check_member(mvmap2315_mc_regs, ch3_dfi_phy_leveling_status, 0x1FFC);
static struct mvmap2315_mc_regs * const mvmap2315_mc
					= (void *)MVMAP2315_MC_BASE;

void sdram_init(struct mvmap2315_sdram_params *sdram_params);
size_t sdram_size_mb(void);

#endif /* __SOC_MARVELL_MVMAP2315_SDRAM_H__ */
